﻿using System.Collections.Generic;
using System.Linq;
using Missbot.Common;
using Missbot.Core.Common;
using Missbot.Service;
using Dolany.UtilityTool;
using Missbot.AIModule.OnlineStore;
using Missbot.AIModule.Pet.Cooking;

namespace Missbot.AIModule.Pet.Expedition
{
    public class ExpeditionScene : DbBaseEntity
    {
        public string Name { get; set; }

        public string Description { get; set; }

        public int Endurance { get; set; }

        public int TimeConsume { get; set; }

        public ExpeditionBonus_Gold GoldBonus { get; set; }

        public ExpeditionBonus_Item ItemBonus { get; set; }

        public ExpeditionBonus_Flavoring FlavoringBonus { get; set; }
    }

    public static class ExpeditionSceneDA
    {
        public static int Level(this ExpeditionScene entity)
        {
            var level = 0;
            if (entity.GoldBonus != null)
            {
                level += entity.GoldBonus.Level;
            }

            if (entity.ItemBonus != null)
            {
                level += entity.ItemBonus.Level;
            }

            if (entity.FlavoringBonus != null)
            {
                level += entity.FlavoringBonus.Level;
            }

            return level;
        }

        /// <summary>
        /// 获取奖励
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="UserID"></param>
        /// <returns></returns>
        public static ExpeditionAward Award(this ExpeditionScene entity, string UserID)
        {
            var award = new ExpeditionAward {Name = entity.Name};
            if (entity.GoldBonus != null)
            {
                award.Gold = Rander.RandRange(entity.GoldBonus.Min, entity.GoldBonus.Max);
                var osPerson = OSPersonDA.GetPerson(UserID);
                osPerson.Golds += award.Gold;
                osPerson.Update();
            }

            if (entity.ItemBonus != null)
            {
                var count = Rander.RandRange(entity.ItemBonus.Min, entity.ItemBonus.Max);
                award.Items = Enumerable.Range(0, count).Select(_ => entity.ItemBonus.Options.RandElement()).ToList();
                var itemColle = ItemCollectionDA.Get(UserID);
                foreach (var item in award.Items)
                {
                    itemColle.ItemIncome(item);
                }
            }

            if (entity.FlavoringBonus != null)
            {
                var count = Rander.RandRange(entity.FlavoringBonus.Min, entity.FlavoringBonus.Max);
                award.Flavorings = Enumerable.Range(0, count).Select(_ => entity.FlavoringBonus.Options.RandElement()).ToList();
                var flavoringRec = CookingRecordDA.Get(UserID);
                foreach (var flavoring in award.Flavorings)
                {
                    flavoringRec.FlavoringIncome(flavoring);
                }
                
                flavoringRec.Update();
            }

            return award;
        }

        public static string Format(this ExpeditionScene entity, int curEndurance)
        {
            var str = $"【{entity.Name}】：{entity.Description}\n耐力：{entity.Endurance}({curEndurance})     耗时：{entity.TimeConsume}分钟\n奖励：";
            if (entity.GoldBonus != null)
            {
                str += $"  金币：{LevelHelper.LevelToStars(entity.GoldBonus.Level)}";
            }

            if (entity.ItemBonus != null)
            {
                str += $"  物品：{LevelHelper.LevelToStars(entity.ItemBonus.Level)}";
            }

            if (entity.FlavoringBonus != null)
            {
                str += $"  调味料：{LevelHelper.LevelToStars(entity.FlavoringBonus.Level)}";
            }

            return str;
        }

        public static string Format(this ExpeditionScene entity)
        {
            var str = $"【{entity.Name}】\n    {entity.Description}\n耐力：{entity.Endurance}\n耗时：{entity.TimeConsume}分钟";
            if (entity.GoldBonus != null)
            {
                str += $"\n金币奖励：{LevelHelper.LevelToStars(entity.GoldBonus.Level)}";
            }

            if (entity.ItemBonus != null)
            {
                str += $"\n物品奖励：{LevelHelper.LevelToStars(entity.ItemBonus.Level)}";
            }

            if (entity.FlavoringBonus != null)
            {
                str += $"\n调味料奖励：{LevelHelper.LevelToStars(entity.FlavoringBonus.Level)}";
            }

            return str;
        }

        /// <summary>
        /// 获取所有远征场景
        /// </summary>
        /// <returns></returns>
        public static List<ExpeditionScene> GetAll()
        {
            return MongoService<ExpeditionScene>.Get();
        }
    }

    /// <summary>
    /// 远征奖励
    /// </summary>
    public class ExpeditionAward
    {
        /// <summary>
        /// 远征地点
        /// </summary>
        public string Name { get; init; }

        /// <summary>
        /// 金币奖励
        /// </summary>
        public int Gold { get; set; }

        /// <summary>
        /// 物品奖励
        /// </summary>
        public List<string> Items { get; set; } = new();

        /// <summary>
        /// 调味料奖励
        /// </summary>
        public List<string> Flavorings { get; set; } = new();

        public override string ToString()
        {
            var msgList = new List<string> {$"恭喜你在 【{Name}】 的伟大远征中获得以下奖励："};
            if (Gold > 0)
            {
                msgList.Add($"金币：{Gold.CurencyFormat()}");
            }

            if (!Items.IsNullOrEmpty())
            {
                msgList.Add($"物品：{string.Join(",", Items.GroupBy(p => p).Select(p => $"{p.Key}*{p.Count()}"))}");
            }

            if (!Flavorings.IsNullOrEmpty())
            {
                msgList.Add($"调味料：{string.Join(",", Flavorings.GroupBy(p => p).Select(p => $"{p.Key}*{p.Count()}"))}");
            }

            return string.Join("\n", msgList);
        }
    }

    /// <summary>
    /// 远征奖励（金币）
    /// </summary>
    public class ExpeditionBonus_Gold
    {
        /// <summary>
        /// 最小奖励
        /// </summary>
        public int Min { get; set; }

        /// <summary>
        /// 最大奖励
        /// </summary>
        public int Max { get; set; }

        /// <summary>
        /// 奖励等级
        /// </summary>
        public int Level
        {
            get
            {
                return Max switch
                {
                    > 1000 => 5,
                    > 600 => 4,
                    > 400 => 3,
                    > 200 => 2,
                    _ => 1
                };
            }
        }
    }

    /// <summary>
    /// 远征奖励（物品）
    /// </summary>
    public class ExpeditionBonus_Item
    {
        /// <summary>
        /// 最小奖励数量
        /// </summary>
        public int Min { get; set; }

        /// <summary>
        /// 最大奖励数量
        /// </summary>
        public int Max { get; set; }

        /// <summary>
        /// 物品备选项
        /// </summary>
        public string[] Options { get; set; }

        /// <summary>
        /// 奖励等级
        /// </summary>
        public int Level
        {
            get
            {
                var models = AutofacSvc.Resolve<HonorSvc>().FishableItems.Where(item => Options.Contains(item.Name));
                var sumPrice = models.Max(m => m.Price) * Max;
                return sumPrice switch
                {
                    > 3000 => 5,
                    > 2000 => 4,
                    > 1000 => 3,
                    > 500 => 2,
                    _ => 1
                };
            }
        }
    }

    /// <summary>
    /// 远征奖励（调味料）
    /// </summary>
    public class ExpeditionBonus_Flavoring
    {
        /// <summary>
        /// 最小奖励数量
        /// </summary>
        public int Min { get; set; }

        /// <summary>
        /// 最大奖励数量
        /// </summary>
        public int Max { get; set; }

        /// <summary>
        /// 调味料备选项
        /// </summary>
        public string[] Options { get; set; }

        /// <summary>
        /// 奖励等级
        /// </summary>
        public int Level
        {
            get
            {
                return Max switch
                {
                    > 5 => 5,
                    > 4 => 4,
                    > 3 => 3,
                    > 2 => 2,
                    _ => 1
                };
            }
        }
    }
}